package com.cleaningcloud.cld.service.impl;

import com.cleaningcloud.cld.api.domain.CldStaff;
import com.cleaningcloud.cld.domain.CldAttendance;
import com.cleaningcloud.cld.domain.CldOvertime;
import com.cleaningcloud.cld.domain.CldOvertimeDetails;
import com.cleaningcloud.cld.domain.CldPayDetails;
import com.cleaningcloud.cld.domain.dto.CldAttendanceDto;
import com.cleaningcloud.cld.domain.dto.CldOvertimeDto;
import com.cleaningcloud.cld.domain.vo.CldAttendanceVo;
import com.cleaningcloud.cld.domain.vo.CldOvertimeDetailsVo;
import com.cleaningcloud.cld.domain.vo.CldOvertimeVo;
import com.cleaningcloud.cld.mapper.CldAttendanceMapper;
import com.cleaningcloud.cld.mapper.CldOvertimeDetailsMapper;
import com.cleaningcloud.cld.mapper.CldOvertimeMapper;
import com.cleaningcloud.cld.mapper.CldStaffMapper;
import com.cleaningcloud.cld.service.ICldAttendanceService;
import com.cleaningcloud.cld.service.ICldOvertimeService;
import com.cleaningcloud.cld.service.ICldPayDetailsService;
import com.cleaningcloud.common.core.utils.DateUtils;
import com.cleaningcloud.common.security.utils.SecurityUtils;
import io.seata.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.List;
import java.util.Map;

/**
 * 加班管理Service业务层处理
 *
 * @author cleaningcloud
 * @date 2024-11-08
 */
@Service
public class CldOvertimeServiceImpl implements ICldOvertimeService {
    @Autowired
    private CldOvertimeMapper cldOvertimeMapper;

    @Autowired
    private CldOvertimeDetailsMapper cldOvertimeDetailsMapper;

    @Autowired
    private ICldAttendanceService attendanceService;

    @Autowired
    private CldAttendanceMapper cldAttendanceMapper;

    @Autowired
    private ICldPayDetailsService cldPayDetailsService;

    @Autowired
    private CldStaffMapper cldStaffMapper;

    /**
     * 查询加班管理
     *
     * @param detailsVo 加班明细数据
     * @return 加班管理
     */
    @Override
    public CldOvertimeVo selectCldOvertimeByOvertimeId(CldOvertimeDetailsVo detailsVo) {
        CldOvertimeVo overtime = cldOvertimeMapper.selectCldOvertimeByOvertimeId(detailsVo.getOvertimeId());
        if(null != overtime){
            List<CldOvertimeDetailsVo> detailsList = cldOvertimeMapper.getCldOvertimeDetailsByOvertimeId(detailsVo);
            if(!detailsList.isEmpty()){
                overtime.setDetailsList(detailsList);
            }else{
                throw new RuntimeException("未找到加班明细数据");
            }
        }
        return overtime;
    }

    /**
     * 查询加班管理列表
     *
     * @param cldOvertime 加班管理
     * @return 加班管理
     */
    @Override
    public List<CldOvertimeVo> selectCldOvertimeList(CldOvertimeDto cldOvertime) {
        return cldOvertimeMapper.selectCldOvertimeList(cldOvertime);
    }

    /**
     * 新增加班管理
     *
     * @param cldOvertime 加班管理
     * @return 结果
     */
    @Override
    @Transactional
    public int insertCldOvertime(CldOvertimeDto cldOvertime) {
        cldOvertime.setCreateTime(DateUtils.getNowDate());
        cldOvertime.setCreateId(SecurityUtils.getUserId());
        cldOvertime.setCreateName(SecurityUtils.getUsername());
        cldOvertime.setFlag(0L);
        cldOvertime.setConfirmStatus(0L);
        cldOvertimeMapper.insertCldOvertime(cldOvertime);
        if (!cldOvertime.getDetailsList().isEmpty()) {
            for (CldOvertimeDetails cldOvertimeDetails : cldOvertime.getDetailsList()) {
                // 查询该人员是否存在加班信息
                CldOvertimeDto query = new CldOvertimeDto();
                query.setStaffId(cldOvertimeDetails.getStaffId());
                query.setStartTime(cldOvertime.getStartTime());
                query.setEndTime(cldOvertime.getEndTime());
                CldOvertime overtime = cldOvertimeMapper.checkwhetherOvertime(query);
                if (overtime != null) {
                    CldStaff cldStaff = cldStaffMapper.selectCldStaffByStaffId(cldOvertimeDetails.getStaffId());
                    throw new RuntimeException("[" + cldStaff.getStaffName() + "]当日已有加班信息,请勿重复添加！");
                }
                cldOvertimeDetails.setOvertimeId(cldOvertime.getOvertimeId());
                cldOvertimeDetails.setIsConfrim(0L);
                cldOvertimeDetails.setIsExamine(0L);
                cldOvertime.setStaffId(cldOvertimeDetails.getStaffId());
                // 修改当天考勤数据
                CldAttendance cldAttendance = isAttendance(cldOvertime);
                if (cldAttendance != null) {
                    cldOvertimeDetails.setAttendanceId(String.valueOf(cldAttendance.getAttendanceId()));
                }
            }
            cldOvertimeDetailsMapper.batchInsertCldOvertimeDetails(cldOvertime.getDetailsList());
        }
        return 1;
    }

    public CldAttendance isAttendance(CldOvertimeDto cldOvertime) {

        LocalDate startDate = cldOvertime.getStartTime().toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDate(); // 转换开始日期
        LocalDate endDate = cldOvertime.getEndTime().toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDate(); // 转换结束日期
        CldAttendanceDto attendanceQuery = new CldAttendanceDto();
        attendanceQuery.setStaffId(cldOvertime.getStaffId());
        attendanceQuery.setProjectId(cldOvertime.getOvertimeType() == 2 ? cldOvertime.getNewProjectId() : cldOvertime.getProjectId());
        attendanceQuery.setAttendanceYear(startDate.getYear());
        attendanceQuery.setAttendanceMonth(startDate.getMonthValue());
        attendanceQuery.setAttendanceDay(startDate.getDayOfMonth());
        List<CldAttendanceVo> attendanceList = attendanceService.selectCldAttendanceList(attendanceQuery);
        if (!attendanceList.isEmpty()) {
            CldAttendance attendance = attendanceList.get(0);
            attendance.setEchoGoToWorkTimeOvertime(DateUtils.dateToLocalDateTime(cldOvertime.getStartTime()));
            attendance.setEchoGoOffWorkTimeOvertime(DateUtils.dateToLocalDateTime(cldOvertime.getEndTime()));
            attendance.setProjectId(cldOvertime.getProjectId());
            if (cldOvertime.getOvertimeType() == 2) {
                attendance.setIsOutExtProject(1L);
            } else {
                attendance.setIsInThisProject(1L);
            }
            cldAttendanceMapper.updateCldAttendance(attendance);
            return attendance;
        }
        return null;
    }

    /**
     * 修改加班管理
     *
     * @param cldOvertime 加班管理
     * @return 结果
     */
    @Override
    public int updateCldOvertime(CldOvertimeDto cldOvertime) {
        if (!cldOvertime.getDetailsList().isEmpty()) {
            for (CldOvertimeDetails cldOvertimeDetails : cldOvertime.getDetailsList()) {
                // 修改当天考勤数据
                cldOvertime.setStaffId(cldOvertimeDetails.getStaffId());
                CldAttendance cldAttendance = isAttendance(cldOvertime);
                if (cldAttendance != null) {
                    cldOvertimeDetails.setAttendanceId(String.valueOf(cldAttendance.getAttendanceId()));
                }
            }
        }
        return cldOvertimeMapper.updateCldOvertime(cldOvertime);
    }

    /**
     * @Author Shaw
     * @Description 加班审核
     * @date: 2025-10-29 11:35
     * @param: //TODO
     */
    @Override
    @Transactional
    public int auditCldOvertime(CldOvertimeDetails cldOvertimeDetails) {
        CldOvertimeDetailsVo cldOvertimeDetailsVo = cldOvertimeDetailsMapper.selectCldOvertimeDetailsByOvertimeDetailsId(cldOvertimeDetails.getOvertimeDetailsId());
        if (cldOvertimeDetailsVo == null) {
            throw new RuntimeException("加班信息获取失败");
        }
        if (cldOvertimeDetailsVo.getIsExamine() == 1) {
            throw new RuntimeException("该加班信息已审核,请勿重复操作");
        }
        cldOvertimeDetailsVo.setIsExamine(1L);
        cldOvertimeDetailsVo.setExamineUserId(SecurityUtils.getUserId());
        cldOvertimeDetailsVo.setExamineTime(DateUtils.getNowDate());

        //判断考勤组ID是否为空
        if(StringUtils.isNotBlank(cldOvertimeDetailsVo.getAttendanceId())){
            String[] attendance = cldOvertimeDetailsVo.getAttendanceId().split(",");
            for (int i = 0; i < attendance.length; i++){
                CldAttendanceVo attendanceVo =  cldAttendanceMapper.selectCldAttendanceByAttendanceId(Long.parseLong(attendance[i]));
                if(null != attendanceVo){
                    // 审核通过 新增员工薪酬明细
                    CldPayDetails cldPayDetails = new CldPayDetails();
                    cldPayDetails.setProjectId(cldOvertimeDetailsVo.getOvertimeType() == 2 ? cldOvertimeDetailsVo.getNewProjectId() : cldOvertimeDetailsVo.getProjectId());
                    cldPayDetails.setYear(attendanceVo.getAttendanceYear());
                    cldPayDetails.setMonth(attendanceVo.getAttendanceMonth());
                    cldPayDetails.setDay(attendanceVo.getAttendanceDay());
                    cldPayDetails.setStaffId(cldOvertimeDetailsVo.getStaffId());
                    cldPayDetails.setPayType(4L);//加班工资
                    cldPayDetails.setMoney(cldOvertimeDetailsVo.getOvertimeMoney());
                    cldPayDetails.setProduceTime(DateUtils.getNowDate());
                    cldPayDetails.setProjectPostId(cldOvertimeDetailsVo.getProjectPostId());
                    cldPayDetails.setIsAlgorithm(1L);//加
                    cldPayDetails.setBusinessId(cldOvertimeDetailsVo.getOvertimeId());
                    if(cldOvertimeDetailsVo.getOvertimeType() == 1){
                        cldPayDetails.setRemark("本项目加班");
                    }else if(cldOvertimeDetailsVo.getOvertimeType() == 2){
                        cldPayDetails.setRemark("外项目加班");
                    }else{
                        cldPayDetails.setRemark("工程项目加班");
                    }
                    cldPayDetailsService.insertCldPayDetails(cldPayDetails);
                }else{
                    throw new RuntimeException("未找到考勤数据");
                }
            }
        }
        return cldOvertimeDetailsMapper.updateCldOvertimeDetails(cldOvertimeDetailsVo);
    }

    /**
     * 批量删除加班管理
     *
     * @param overtimeIds 需要删除的加班管理主键
     * @return 结果
     */
    @Override
    public int deleteCldOvertimeByOvertimeIds(Long[] overtimeIds) {
        return cldOvertimeMapper.deleteCldOvertimeByOvertimeIds(overtimeIds);
    }

    /**
     * 删除加班管理信息
     *
     * @param overtimeId 加班管理主键
     * @return 结果
     */
    @Override
    public int deleteCldOvertimeByOvertimeId(Long overtimeId) {
        return cldOvertimeMapper.deleteCldOvertimeByOvertimeId(overtimeId);
    }

    @Override
    public Map<String, Object> selectOvertimeAnalyze(CldOvertimeDto cldOvertime) {
        return cldOvertimeMapper.selectOvertimeAnalyze(cldOvertime);
    }
}
